#pragma once
#include<vector>
#include"VPE.h"
#include"VLDST.h"
#include"../../execution_module/write_delay_control/write_delay_control.h"


class VPU {
public:
    VPU(V_memory* am, RegisterFile* rf, WriteControlModule* wcm) : AM(am), RF(rf), WCM(wcm) {
        VPEs.assign(16, NULL);
        for (int i = 0; i < VPEs.size(); i++) {
            VPEs.at(i) = new VPE(i, this->RF);
        }
        vldst0 = new VLDST_0(am, wcm, rf);
        vldst1 = new VLDST_1(am, wcm, rf);
    }
    ~VPU() {
        for (int i = 0; i < VPEs.size(); i++) {
            delete VPEs.at(i);
        }
        delete vldst0;
        delete vldst1;
    }

    // void input_instr(int src1, int src2, int src3, int dst);
    // //VPU的Execute函数不需要返回值，直接将dst结果存回寄存器堆
    // void Execute();
    void Execute_VMAC1(instruction* vmac_instr);
    void Execute_VMAC2(instruction* vmac_instr);
    void Execute_VMAC3(instruction* vmac_instr);
    void Execute_VIEU(instruction* vmac_instr);


private:
    std::vector<VPE*> VPEs;
    VLDST_0* vldst0;
    VLDST_1* vldst1;
    //以下三个vector用于存储三个VMAC计算完成后准备存入dst寄存器的结果
    // std::vector<uint64_t>* VMAC1_dst_reg_values;
    // std::vector<uint64_t>* VMAC2_dst_reg_values;
    // std::vector<uint64_t>* VMAC3_dst_reg_values;
    //以下四个vector用于存储两个LDST模块，进行store
    std::vector<uint64_t>* LDST1_dst1_reg_values;
    std::vector<uint64_t>* LDST1_dst2_reg_values;
    std::vector<uint64_t>* LDST2_dst1_reg_values;
    std::vector<uint64_t>* LDST2_dst2_reg_values;
    //TODO:VPU需要模拟一个向量控制寄存器么？（如果不影响正确性和功能应该可以不需要模拟）
    //TODO:此处是否需要多套src和dst？考虑三个VMAC的执行方式，目前先考虑一套的情况
    int src_1;
    int src_2;
    int src_3;
    int dst;

    //内部保存的其他实体的指针，用于访问其数据
    //传给VLDST
    V_memory* AM;
    //传给VPE
    RegisterFile* RF;
    WriteControlModule* WCM;
};